package cn.mafangui.hotel.service.impl;

import cn.mafangui.hotel.entity.CheckIn;
import cn.mafangui.hotel.entity.Order;
import cn.mafangui.hotel.entity.Room;
import cn.mafangui.hotel.entity.RoomType;
import cn.mafangui.hotel.enums.ExceptionEnum;
import cn.mafangui.hotel.enums.OrderStatus;
import cn.mafangui.hotel.enums.RoomStatus;
import cn.mafangui.hotel.exception.HotelException;
import cn.mafangui.hotel.mapper.CheckInMapper;
import cn.mafangui.hotel.mapper.OrderMapper;
import cn.mafangui.hotel.service.CheckInService;
import cn.mafangui.hotel.service.OrderService;
import cn.mafangui.hotel.service.RoomService;
import cn.mafangui.hotel.service.RoomTypeService;
import cn.mafangui.hotel.utils.AssertUtils;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;

@Service
public class CheckInServiceImpl implements CheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private OrderService orderService;
    @Autowired
    private RoomTypeService roomTypeService;
    @Autowired
    private RoomService roomService;

    @Override
    public int insert(CheckIn checkIn) {
        return checkInMapper.insert(checkIn);
    }

    /**
     * 入住登记
     * 必须入参:  订单id  房间类型id
     * @param checkIn
     * 1.获取订单
     * 2.获取房间类型
     * 3.获取房间 - 根据房间类型得到房间号id(把房间空闲状态改为入住状态) , 根据房间找到房间
     * 4.更新房间类型的rest字段 -1
     * 5.更新订单状态为已入住
     * 6. 插入入住登记表
     *
     * @return
     */
    @Override
    @Transactional
    public Room checkIn(CheckIn checkIn) throws HotelException {
        if(checkIn.getIds() == null){
            checkIn.setIds("1111111111111111");
        }
        // 1. 找到订单
        Order order = orderService.selectById(checkIn.getOrderId());
        System.out.println("找到的订单: " + JSON.toJSONString(order));
        // 2. 找到订单对应的房间类型
        RoomType rt = roomTypeService.selectById(order.getRoomTypeId());
        System.out.println("找到的房间类型: " + JSON.toJSONString(rt));
        // 3. 找到房间类型下面的房间
        Room r = roomService.selectById(roomService.inRoom(order.getRoomTypeId()));
        System.out.println("找到的房间: " + JSON.toJSONString(r));
        // 4 更新房间类型下面的剩余数量?
        checkIn.setRoomType(rt.getRoomType());
        checkIn.setRoomId(r.getRoomId());
        checkIn.setRoomNumber(r.getRoomNumber());
        roomTypeService.updateRest(rt.getTypeId(),-1);
        // 5. 更新订单的状态为已入住
        order.setOrderStatus(OrderStatus.CHECK_IN.getCode());
        orderService.update(order);
        // 6. 插入一条入住登记信息
        checkInMapper.insert(checkIn);
        return r;
    }

    /**
     * 退房登记
     * 1.获取房间r - 根据房间号
     * 2.获取房型 - 根据房间r.typeId
     * 3.获取checkIn - 根据房间号
     * 4. 设置房间状态为 空闲
     * 5. 将房间类型的rest +1
     * 6. 更新登记信息(离开时间,修改时间)
     * @param roomNumber
     * @return
     */
    @Override
    public int checkOut(String  roomNumber) throws HotelException {
        Room r = roomService.selectByNumber(roomNumber);
        AssertUtils.assertNotNull(r, ExceptionEnum.NOT_FOUND_ROOM);

        RoomType ty = roomTypeService.selectById(r.getTypeId());
        AssertUtils.assertNotNull(ty, ExceptionEnum.NOT_FOUND_ROOM_TYPE);

        CheckIn checkIn = checkInMapper.selectLatestByRoomNumber(roomNumber);
        AssertUtils.assertNotNull(checkIn, ExceptionEnum.NOT_FOUND_CHECK_IN);

        // 更改订单状态
        Order order = orderService.selectById(checkIn.getOrderId());
        order.setOrderStatus(OrderStatus.CHECK_OUT.getCode());
        AssertUtils.assertTrue(orderService.update(order) == 1, ExceptionEnum.NOT_FOUND_ROOM);


        r.setRoomStatus(RoomStatus.AVAILABLE.getCode());
        if(roomService.update(r) <=0 ) {
            return -3;
        }
        if (roomTypeService.updateRest(ty.getTypeId(),1)<=0) {
            return -2;
        }
        return checkInMapper.checkOut(checkIn.getCheckInId());
    }

    @Override
    public int delete(int checkInId) {
        return checkInMapper.deleteByPrimaryKey(checkInId);
    }

    @Override
    public int update(CheckIn checkIn) {
        return checkInMapper.updateByPrimaryKeySelective(checkIn);
    }



    @Override
    public int updateByRoomNumber(String roomNumber) {
        return checkInMapper.updateByRoomNumber(roomNumber);
    }

    @Override
    public CheckIn selectById(int checkInId) {
        return checkInMapper.selectByPrimaryKey(checkInId);
    }

    @Override
    public List<CheckIn> selectAll() {
        return checkInMapper.selectAll();
    }
}
